package com.rtf.framework.monitor;

import com.rtf.framework.monitor.export.*;
import com.rtf.framework.monitor.support.AppMonitorNameConverter;
import com.google.common.collect.Lists;
import io.micrometer.core.instrument.Clock;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.CollectorRegistry;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Set;

/**
 * 默认指标监控导出对象
 * @Author : liupeng
 * @Date : 2020-02-01
 * @Modified By
 */
@Slf4j
public class AppMonitorDefaultEndpoint {

    public static final List<String> includeMetrics  = Lists.newArrayList("jvm" , "ribbon" , "hystrix" , "redis" , "url") ;

    @Setter
    @Getter
    private AppMonitorNameConverter hystrixCommandNameConverter = new AppMonitorNameConverter.Default() ;

    @Setter
    @Getter
    private AppMonitorNameConverter hystrixGroupNameConverter = new AppMonitorNameConverter.Default() ;

    @Setter
    @Getter
    private AppMonitorNameConverter clientNameConverter = new AppMonitorNameConverter.Default() ;

    @Setter
    @Getter
    private Set<String> clientNames ;

    @Getter
    private CollectorRegistry collectorRegistry = CollectorRegistry.defaultRegistry ;

    private AppJvmExport appJvmExport = new AppJvmExport() ;

    private AppRibbonExport appRibbonExport = new AppRibbonExport() ;

    private AppHystrixExport appHystrixExport = new AppHystrixExport() ;

    private AppUrlTraceExport appUrlTraceExport = new AppUrlTraceExport() ;

    private AppRedisExport appRedisExport = new AppRedisExport() ;

    /**
     * 抓取指标并导出
     * @param targetMetrics
     * @return
     */
    public String scrape(List<String> targetMetrics ) {
        return scrape( targetMetrics , null ) ;
    }

    /**
     * 抓取指标并导出
     * @param targetMetrics
     * @param otherExporters
     * @return
     */
    public String scrape(List<String> targetMetrics , List<AppMonitorExporter> otherExporters) {
        if( targetMetrics==null || targetMetrics.size()<1 ){
            targetMetrics = includeMetrics ;
        }

        // 清理注册的指标信息
        collectorRegistry.clear();
        // 构建指标注册信息
        PrometheusMeterRegistry registry = new PrometheusMeterRegistry(
                PrometheusConfig.DEFAULT , collectorRegistry , Clock.SYSTEM) ;
        // jvm监控
        try{
            if( targetMetrics.contains("jvm") ){
                appJvmExport.export( collectorRegistry ) ;
            }
        }catch( Exception e ){
//            log.error( "jvm监控指标获取失败 : {}" , e.getMessage() ) ;
        }

        try{
            if( targetMetrics.contains("redis") ){
                appRedisExport.export( collectorRegistry ) ;
            }
        }catch( Exception e ){
//            log.error( "redis监控指标获取失败 : {}" , e.getMessage() ) ;
        }

        try{
            if( targetMetrics.contains("ribbon") ){
                AppRibbonExport.setClientNames( clientNames ) ;
                appRibbonExport.export( collectorRegistry ) ;
            }
        }catch( Exception e ){
//            log.error( "ribbon监控指标获取失败 : {}" , e.getMessage() ) ;
        }

        try{
            if( targetMetrics.contains("hystrix") ){
                appHystrixExport.export( collectorRegistry ) ;
            }
        }catch( Exception e ){
//            log.error( "hystrix监控指标获取失败 : {}" , e.getMessage() ) ;
        }

        try{
            if( targetMetrics.contains("url") ){
                appUrlTraceExport.export( collectorRegistry ) ;
            }
        }catch( Exception e ){
//            log.error( "url监控指标获取失败 : {}" , e.getMessage() ) ;
        }

        try{
            if( otherExporters!=null ){
                for (AppMonitorExporter otherExporter : otherExporters) {
                    otherExporter.export( collectorRegistry ) ;
                }
            }
        }catch( Exception e ){
            e.printStackTrace();
        }

        // 生成prometheus指标信息
        return registry.scrape();
    }

}
